﻿using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Crm2011.Framework.Core
{
    /// <summary>
    /// This Helper class supports the easy serialization and deserialization of objects.
    /// It is independed of the type of the object.
    /// </summary>
    public static class SerializationHelper
    {
        /// <summary>
        /// Deserializes the specified serialized object, using an DataContractSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="serializedObject">The serialized object.</param>
        /// <returns></returns>
        public static T DeserializeDc<T>(string serializedObject)
        {
            //Contract.Requires(!string.IsNullOrEmpty(serializedObject));
            using (StringReader stringReader = new StringReader(serializedObject))
            {
                using (XmlReader xmlReader = XmlReader.Create(stringReader))
                {
                    var serializer = new DataContractSerializer(typeof (T));
                    return (T) serializer.ReadObject(xmlReader);
                }
            }
        }



        #region JSON Serialization


        /*
        ProjectConfiguration pc = new ProjectConfiguration { AutoPublish = true, ConnectionString = "abc" };
        WebResource webResource = new WebResource { Name = "WRName", WebResourceType = new OptionSetValue(3) };

        pc.WebResourceFileMappings = new List<WebResourceFileMapping>
            {
                new WebResourceFileMapping(webResource, "filename", true)
            };
        string result = SerializationHelper.SerializeJson(pc);
        Trace.Default.Debug(result);
        ProjectConfiguration pc1 =SerializationHelper.DeserializeJson<ProjectConfiguration>(result);
       */



        /// <summary>
        /// Serializes the specified value, using an DataContractSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string SerializeDc<T>(T value)
        {
            StringBuilder result = new StringBuilder();

            XmlWriterSettings settings = new XmlWriterSettings {Indent = true};
            using (XmlWriter xmlWriter = XmlWriter.Create(result, settings))
            {
                var serializer = new DataContractSerializer(typeof (T));
                serializer.WriteObject(xmlWriter, value);
            }
            return result.ToString();
        }



        /// <summary>
        /// Serializes the specified value, using an DataContractSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string SerializeJson<T>(T value)
        {
            string jsonString;
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof (T));
                ser.WriteObject(ms, value);
                jsonString = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
            }
            return jsonString;
        }


        #endregion



        /// <summary>
        /// Deserializes the specified serialized object, using an DataContractSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="jsonString">The serialized object.</param>
        /// <returns></returns>
        public static T DeserializeJson<T>(string jsonString)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof (T));
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
            return (T) ser.ReadObject(ms);
        }



        /// <summary>
        /// Deserializes the specified serialized object, using an XmlSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="serializedObject">The serialized object.</param>
        /// <returns></returns>
        public static T Deserialize<T>(string serializedObject)
        {
            //Contract.Requires(!string.IsNullOrEmpty(serializedObject));
            XmlSerializer xmlSerializer = new XmlSerializer(typeof (T));
            using (StringReader stringReader = new StringReader(serializedObject))
            {
                return (T) xmlSerializer.Deserialize(stringReader);
            }
        }



        /// <summary>
        /// Serializes the specified value, using an XmlSerializer.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string Serialize<T>(T value)
        {
            var xmlSerializer = new XmlSerializer(typeof (T));
            using (TextWriter textWriter = new StringWriter())
            {
                xmlSerializer.Serialize(textWriter, value);
                return textWriter.ToString();
            }
        }
    }
}